﻿using Ranger.App;
using TextMateSharp.Grammars;
using TextMateSharp.Registry;
using TextMateSharp.Themes;

Console.WriteLine("Hello, World!");

var filePath = args.Length == 0 ? StringExtensions.CodePath : args[0];

int folderLine = -1;
bool isFileReturn = false;
FolderVisual();

void FolderVisual()
{
    while (true)
    {
        if (!Directory.Exists(filePath))
        {
            if (File.Exists(filePath))
            {
                FileVisual();
                if(isFileReturn)
                    return;
            }
            else 
                return;
        }

        if (!Directory.Exists(filePath))return;
        var finder = new DirectoryInfo(filePath);
        Console.Title = finder.Name;
        var infos = finder.GetFileSystemInfos();
        Console.Clear();
        for (int i = 0; i < infos.Length; i++)
        {
            if (folderLine == i)
                Console.WriteLine("=> " + infos[i]);
            else
                Console.WriteLine(infos[i]);
        }

        var key = Console.ReadKey(true);
        if (key.Key == ConsoleKey.D)
        {
            if (folderLine > -1 && folderLine < infos.Length)
            {
                filePath = infos[folderLine].FullName;
            }
        }

        if (key.Key == ConsoleKey.S)
        {
            if (folderLine < infos.Length - 1)
                folderLine++;
            else
                folderLine = 0;
        }

        if (key.Key == ConsoleKey.W)
        {
            if (folderLine > 0)
                folderLine--;
            else
                folderLine = infos.Length - 1;
        }
        
        if (key.Key == ConsoleKey.A)
        {
            filePath = Path.GetDirectoryName(filePath);
        }

        if (key.Key == ConsoleKey.Q)
        {
            return;
        }
        Console.Clear();
    }
}

void FileVisual()
{
    RegistryOptions options = new RegistryOptions(ThemeName.DarkPlus);
    Registry registry = new Registry(options);
    Theme theme = registry.GetTheme();
    IGrammar grammar = registry.LoadGrammar(options.GetScopeByExtension(Path.GetExtension(filePath)));

    if (grammar == null)
    {
        Console.WriteLine(File.ReadAllText(filePath));
        return;
    }

    IStateStack? ruleStack = null;
    using StreamReader sr = new StreamReader(filePath);
    string? line = sr.ReadLine();

    while (line != null)
    {
        ITokenizeLineResult result = grammar.TokenizeLine(line, ruleStack, TimeSpan.MaxValue);

        ruleStack = result.RuleStack;

        foreach (IToken token in result.Tokens)
        {
            int startIndex = (token.StartIndex > line.Length) ? line.Length : token.StartIndex;
            int endIndex = (token.EndIndex > line.Length) ? line.Length : token.EndIndex;

            int foreground = -1;
            int background = -1;
            int fontStyle = -1;

            foreach (var themeRule in theme.Match(token.Scopes))
            {
                if (foreground == -1 && themeRule.foreground > 0)
                    foreground = themeRule.foreground;

                if (background == -1 && themeRule.background > 0)
                    background = themeRule.background;

                if (fontStyle == -1 && themeRule.fontStyle > 0)
                    fontStyle = themeRule.fontStyle;
            }

            ConsoleRendering.WriteToken(line.SubstringAtIndexes(startIndex, endIndex),
                foreground, background, fontStyle, theme);
        }

        Console.WriteLine();
        line = sr.ReadLine();
    }
    var key = Console.ReadKey();
    if (key.Key == ConsoleKey.Q)
    {
        isFileReturn = true;
        return;
    }

    if (key.Key == ConsoleKey.A)
    {
        filePath = Path.GetDirectoryName(filePath);
        return;
    }
}